// 泛型
// function identity<T>(arg: T): T {
//   return arg
// }

// let output = identity<string>('myString')
// console.log(output)

// let output2 = identity('myString')
// console.log(output2)

// 泛型类型
// function identity<T>(arg: T): T {
//   return arg
// }

// let myIdentity: <T>(arg: T) => T = identity

// let myIdentity: <U>(arg: U) => U = identity

// 带有调用签名的对象字面量
// let myIdentity: {<T>(arg: T): T} = identity

// 泛型接口
// interface GenericIdentityFn {
//   <T>(arg: T): T
// }

// function identity<T>(arg: T): T {
//   return arg
// }

// let myIdentity: GenericIdentityFn = identity

// interface GenericIdentityFn<T> {
//   (arg: T): T
// }

// function identity<T>(arg: T): T {
//   return arg
// }

// let myIdentity: GenericIdentityFn<number> = identity

// 泛型类
// class GenericNumber<T> {
//   zeroValue: T
//   add: (x: T, y: T) => T
// }

// let myGenericNumber = new GenericNumber<number>()
// myGenericNumber.zeroValue = 0
// myGenericNumber.add = function(x, y) { return x + y }

// let stringNumberic = new GenericNumber<string>()
// stringNumberic.zeroValue = ''
// stringNumberic.add = function(x, y) { return x + y }
// console.log(stringNumberic.add(stringNumberic.zeroValue, 'test'))

// 泛型约束
// interface Lengthwise {
//   length: number
// }

// function loggingIdentity<T extends Lengthwise>(arg: T): T {
//   console.log(arg.length)
//   return arg
// }

// loggingIdentity(3) // 报错，类型“number”的参数不能赋给类型“Lengthwise”的参数
// loggingIdentity({ length: 10, value:3 })


// 在泛型约束中使用类型参数
// function getProperty(obj: T, key: K) {
//   return obj[key]
// }

// let x = { a: 1, b: 2, c: 3, d: 4 }
// getProperty(x, 'a')
// getProperty(x, 'm')

// 在泛型里使用类类型
// function create<T>(c: { new(): T }): T {
//   return new c()
// }


